# datafier.rb
# Copyright (c) 2009 Alex Wilson
# Licensed under the MIT license (see LICENSE in the distribution root dir)

require "fetcher"
require "timetable"
require "rexml/document"

module Timetable

# A wrapper that uses TimetableFetcher to load courses from mySI-net and then
# parse the resulting XML into constructed Course, Series, Group and Session
# objects ready for use.
#
# It also supports dumping these objects, or their intermediates, to disk for
# later use.
class CourseFactory
	# Constructs a new CourseFactory to be used for fetching the array of
	# courses given
	def initialize(courses)
		@courses = courses
	end
	
	# Create a new TimetableFetcher and fetch the XML data
	def fetch
		@fetcher = TimetableFetcher.new(@courses)
		@fetcher.fetch
		@fetcher.tidy
	end
	
	# Dump the unparsed XML to a Marshal file
	def dump(fname="ttfetch.dump")
		f = File.new(fname, "w")
		f.write Marshal.dump(@fetcher)
		f.close
	end
	
	# Load unparsed XML from a Marshal file
	def load(fname="ttfetch.dump")
		f = File.new(fname, "r")
		@fetcher = Marshal.load(f.read)
		f.close
	end
	
	# Parse the fetched XML by calling parse_course_src on each
	# page obtained
	def parse
		@fetcher.srcs.each do |course, src|
			parse_course_src(course, src)
		end
	end

	# Parses an individual course search page
	def parse_course_src(course, src)
		doc = REXML::Document.new src
		
		columns = Array.new
		doc.elements.each("//tr/th") { |th| columns.push th.text }
		
		doc.elements.each("//tr") do |row|
			colidx = 0
			
			hash = Hash.new
			hash['Course'] = course
			row.elements.each("td") do |td|
				txt = td.text
				if not txt
					sp = td.elements['span']
					if sp
						txt = sp.text
						if not txt
							a = sp.elements['a']
							txt = a.text if a
						end
					end
				end
				
				txt = "" unless txt
				hash[columns[colidx]] = txt
				colidx += 1
			end
			
			if hash['Class'] =~ /^[A-Z]{1}[0-9]{0,3}$/ and hash['Start'] and hash['End']
				hash['Weekday'] = hash['Day']
				hash['Class Type'] = hash['Group Name']
				hash['Class Type'] = "" unless hash['Class Type']
				if not (hash['Weekday'].include?("&nbsp;") or hash['Weekday'].include?("TBA")) and not (hash['Start'].include?("&nbsp;") or hash['Start'].include?("TBA"))
				  Session.new(hash)
        end
			end
		end
	end
end

end
